package lnx

/*
#cgo CPPFLAGS: -fPIC -I../SOPTv3.6.2_20210915
#cgo linux LDFLAGS: -fPIC -L${SRCDIR} -Wl,-rpath ${SRCDIR} -lquote -lstdc++

#include "ThostFtdcUserApiDataType.h"
#include "ThostFtdcUserApiStruct.h"
void* qCreateApi();
void* qCreateSpi();
void* qRegisterSpi(void*, void*);
void qSetOnFrontConnected(void*, void*);
int qOnFrontConnected();
void qSetOnFrontDisconnected(void*, void*);
int qOnFrontDisconnected(int nReason);
void qSetOnHeartBeatWarning(void*, void*);
int qOnHeartBeatWarning(int nTimeLapse);
void qSetOnRspUserLogin(void*, void*);
int qOnRspUserLogin(struct CThostFtdcRspUserLoginField *pRspUserLogin, struct CThostFtdcRspInfoField *pRspInfo, int nRequestID, _Bool bIsLast);
void qSetOnRspUserLogout(void*, void*);
int qOnRspUserLogout(struct CThostFtdcUserLogoutField *pUserLogout, struct CThostFtdcRspInfoField *pRspInfo, int nRequestID, _Bool bIsLast);
void qSetOnRspError(void*, void*);
int qOnRspError(struct CThostFtdcRspInfoField *pRspInfo, int nRequestID, _Bool bIsLast);
void qSetOnRspSubMarketData(void*, void*);
int qOnRspSubMarketData(struct CThostFtdcSpecificInstrumentField *pSpecificInstrument, struct CThostFtdcRspInfoField *pRspInfo, int nRequestID, _Bool bIsLast);
void qSetOnRspUnSubMarketData(void*, void*);
int qOnRspUnSubMarketData(struct CThostFtdcSpecificInstrumentField *pSpecificInstrument, struct CThostFtdcRspInfoField *pRspInfo, int nRequestID, _Bool bIsLast);
void qSetOnRspSubForQuoteRsp(void*, void*);
int qOnRspSubForQuoteRsp(struct CThostFtdcSpecificInstrumentField *pSpecificInstrument, struct CThostFtdcRspInfoField *pRspInfo, int nRequestID, _Bool bIsLast);
void qSetOnRspUnSubForQuoteRsp(void*, void*);
int qOnRspUnSubForQuoteRsp(struct CThostFtdcSpecificInstrumentField *pSpecificInstrument, struct CThostFtdcRspInfoField *pRspInfo, int nRequestID, _Bool bIsLast);
void qSetOnRtnDepthMarketData(void*, void*);
int qOnRtnDepthMarketData(struct CThostFtdcDepthMarketDataField *pDepthMarketData);
void qSetOnRtnForQuoteRsp(void*, void*);
int qOnRtnForQuoteRsp(struct CThostFtdcForQuoteRspField *pForQuoteRsp);
void qRelease(void*);
void qInit(void*);
void qJoin(void*);
void qRegisterFront(void*, char *pszFrontAddress);
void qRegisterNameServer(void*, char *pszNsAddress);
void qRegisterFensUserInfo(void*, struct CThostFtdcFensUserInfoField * pFensUserInfo);
void qSubscribeMarketData(void*, char *ppInstrumentID[], int nCount);
void qUnSubscribeMarketData(void*, char *ppInstrumentID[], int nCount);
void qSubscribeForQuoteRsp(void*, char *ppInstrumentID[], int nCount);
void qUnSubscribeForQuoteRsp(void*, char *ppInstrumentID[], int nCount);
void qReqUserLogin(void*, struct CThostFtdcReqUserLoginField *, int);
void qReqUserLogout(void*, struct CThostFtdcUserLogoutField *, int);
#include <stdlib.h>
#include <stdint.h>
*/
import "C"
import (
	"fmt"
	"unsafe"

	"gitee.com/haifengat/gosopt"
	"gitee.com/haifengat/gosopt/define"
)

// Quote 行情接口
type Quote struct {
	gosopt.HFQuote // 组合

	api unsafe.Pointer
}

var q *Quote

// NewQuote new md api instanse
func NewQuote() *Quote {
	q = new(Quote)
	q.Init() // 调用上层的 Init

	q.api = C.qCreateApi()
	spi := C.qCreateSpi()
	C.qRegisterSpi(q.api, spi)

	// req
	q.HFQuote.ReqConnect = func(addr string) {
		front := C.CString(addr)
		C.qRegisterFront(q.api, front)
		defer C.free(unsafe.Pointer(front))
		C.qInit(q.api)
		// C.qJoin(q.api)
	}
	q.HFQuote.Release = func() {
		C.qRelease(q.api)
	}
	q.HFQuote.ReqUserLogin = func(f *define.CThostFtdcReqUserLoginField) {
		C.qReqUserLogin(q.api, (*C.struct_CThostFtdcReqUserLoginField)(unsafe.Pointer(f)), C.int(1))
	}
	q.HFQuote.ReqSubscript = func(instrument string) {
		ppInstrumentID := make([]*C.char, 1)
		ppInstrumentID[0] = (*C.char)(unsafe.Pointer(C.CString(instrument)))
		C.qSubscribeMarketData(q.api, (**C.char)(unsafe.Pointer(&ppInstrumentID[0])), C.int(1))
	}
	q.HFQuote.Init() // 初始化

	C.qSetOnFrontConnected(spi, C.qOnFrontConnected)
	C.qSetOnFrontDisconnected(spi, C.qOnFrontDisconnected)
	C.qSetOnRspUserLogin(spi, C.qOnRspUserLogin)
	C.qSetOnRtnDepthMarketData(spi, C.qOnRtnDepthMarketData)
	return q
}

// reg
//export qOnFrontConnected
func qOnFrontConnected() C.int {
	q.HFQuote.FrontConnected()
	return 0
}

//export qOnFrontDisconnected
func qOnFrontDisconnected(i C.int) C.int {
	q.HFQuote.FrontDisConnected(int(i))
	return 0
}

//export qOnHeartBeatWarning
func qOnHeartBeatWarning(i C.int) C.int {

	fmt.Print()
	return 0
}

//export qOnRspUserLogin
func qOnRspUserLogin(pRspUserLogin *C.struct_CThostFtdcRspUserLoginField, pRspInfo *C.struct_CThostFtdcRspInfoField, i C.int, b C._Bool) C.int {
	pRspUserLoginField := (*define.CThostFtdcRspUserLoginField)(unsafe.Pointer(pRspUserLogin))
	pRspInfoField := (*define.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo))
	q.HFQuote.RspUserLogin(pRspUserLoginField, pRspInfoField)
	return 0
}

//export qOnRspUserLogout
func qOnRspUserLogout(pUserLogout *C.struct_CThostFtdcUserLogoutField, pRspInfo *C.struct_CThostFtdcRspInfoField, i C.int, b C._Bool) C.int {
	pUserLogoutField := (*define.CThostFtdcUserLogoutField)(unsafe.Pointer(pUserLogout))
	pRspInfoField := (*define.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo))
	fmt.Print(pUserLogoutField, pRspInfoField)
	return 0
}

//export qOnRspError
func qOnRspError(pRspInfo *C.struct_CThostFtdcRspInfoField, i C.int, b C._Bool) C.int {
	pRspInfoField := (*define.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo))
	fmt.Print(pRspInfoField)
	return 0
}

//export qOnRspSubMarketData
func qOnRspSubMarketData(pSpecificInstrument *C.struct_CThostFtdcSpecificInstrumentField, pRspInfo *C.struct_CThostFtdcRspInfoField, i C.int, b C._Bool) C.int {
	pSpecificInstrumentField := (*define.CThostFtdcSpecificInstrumentField)(unsafe.Pointer(pSpecificInstrument))
	pRspInfoField := (*define.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo))
	fmt.Print(pSpecificInstrumentField, pRspInfoField)
	return 0
}

//export qOnRspUnSubMarketData
func qOnRspUnSubMarketData(pSpecificInstrument *C.struct_CThostFtdcSpecificInstrumentField, pRspInfo *C.struct_CThostFtdcRspInfoField, i C.int, b C._Bool) C.int {
	pSpecificInstrumentField := (*define.CThostFtdcSpecificInstrumentField)(unsafe.Pointer(pSpecificInstrument))
	pRspInfoField := (*define.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo))
	fmt.Print(pSpecificInstrumentField, pRspInfoField)
	return 0
}

//export qOnRspSubForQuoteRsp
func qOnRspSubForQuoteRsp(pSpecificInstrument *C.struct_CThostFtdcSpecificInstrumentField, pRspInfo *C.struct_CThostFtdcRspInfoField, i C.int, b C._Bool) C.int {
	pSpecificInstrumentField := (*define.CThostFtdcSpecificInstrumentField)(unsafe.Pointer(pSpecificInstrument))
	pRspInfoField := (*define.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo))
	fmt.Print(pSpecificInstrumentField, pRspInfoField)
	return 0
}

//export qOnRspUnSubForQuoteRsp
func qOnRspUnSubForQuoteRsp(pSpecificInstrument *C.struct_CThostFtdcSpecificInstrumentField, pRspInfo *C.struct_CThostFtdcRspInfoField, i C.int, b C._Bool) C.int {
	pSpecificInstrumentField := (*define.CThostFtdcSpecificInstrumentField)(unsafe.Pointer(pSpecificInstrument))
	pRspInfoField := (*define.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo))
	fmt.Print(pSpecificInstrumentField, pRspInfoField)
	return 0
}

//export qOnRtnDepthMarketData
func qOnRtnDepthMarketData(pDepthMarketData *C.struct_CThostFtdcDepthMarketDataField) C.int {
	pDepthMarketDataField := (*define.CThostFtdcDepthMarketDataField)(unsafe.Pointer(pDepthMarketData))
	fmt.Print(pDepthMarketDataField)
	return 0
}

//export qOnRtnForQuoteRsp
func qOnRtnForQuoteRsp(pForQuoteRsp *C.struct_CThostFtdcForQuoteRspField) C.int {
	pForQuoteRspField := (*define.CThostFtdcForQuoteRspField)(unsafe.Pointer(pForQuoteRsp))
	fmt.Print(pForQuoteRspField)
	return 0
}
